<template>
  <div class="product-waterfall-list">
    <!-- 下拉刷新 -->
    <van-pull-refresh
      v-model="refreshing"
      :disabled="loading"
      @refresh="handleRefresh"
      class="pull-refresh-wrapper"
    >
      <!-- 瀑布流容器 -->
      <WaterfallContainer
        ref="waterfallRef"
        :products="displayProducts"
        :column-count="columnCount"
        :gap="gap"
        :min-image-height="minImageHeight"
        :max-image-height="maxImageHeight"
        :show-skeleton="showSkeleton"
        :skeleton-count="skeletonCount"
        :skeleton-columns="skeletonColumns"
        @product-click="handleProductClick"
        @image-load="handleImageLoad"
        @image-error="handleImageError"
        @layout-complete="handleLayoutComplete"
      />
      
      <!-- 上拉加载更多 -->
      <div v-if="hasMore || loading" class="load-more-wrapper">
        <van-loading
          v-if="loading"
          type="spinner"
          size="20"
          text-size="14"
          vertical
        >
          {{ loadingText }}
        </van-loading>
        <div v-else-if="hasMore" class="load-more-trigger" @click="handleLoadMore">
          <van-icon name="arrow-down" />
          <span>点击加载更多</span>
        </div>
      </div>
      
      <!-- 没有更多数据 -->
      <div v-if="!hasMore && !loading && displayProducts.length > 0" class="no-more">
        <van-divider>没有更多商品了</van-divider>
      </div>
      
      <!-- 空状态 -->
      <van-empty
        v-if="!loading && !refreshing && displayProducts.length === 0"
        :image="emptyImage"
        :description="emptyDescription"
        class="empty-state"
      >
        <template v-if="showRetry" #default>
          <van-button
            type="primary"
            size="small"
            @click="handleRetry"
          >
            重新加载
          </van-button>
        </template>
      </van-empty>
    </van-pull-refresh>
    
    <!-- 回到顶部 -->
    <van-back-top
      v-if="showBackTop"
      :offset="backTopOffset"
      :z-index="backTopZIndex"
      @click="handleBackTop"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, nextTick, watch } from 'vue'
import { showToast } from 'vant'
import WaterfallContainer from './WaterfallContainer.vue'
import type { ProductItem } from './ProductWaterfallCard.vue'

// Props
interface Props {
  // 数据相关
  products?: ProductItem[]
  loadMore?: () => Promise<ProductItem[]>
  refresh?: () => Promise<ProductItem[]>
  
  // 布局相关
  columnCount?: number
  gap?: number
  minImageHeight?: number
  maxImageHeight?: number
  
  // 加载状态
  loading?: boolean
  hasMore?: boolean
  loadingText?: string
  
  // 骨架屏
  showSkeleton?: boolean
  skeletonCount?: number
  skeletonColumns?: number
  
  // 空状态
  emptyImage?: string
  emptyDescription?: string
  showRetry?: boolean
  
  // 回到顶部
  showBackTop?: boolean
  backTopOffset?: number
  backTopZIndex?: number
  
  // 自动加载更多
  autoLoadMore?: boolean
  loadMoreOffset?: number
}

const props = withDefaults(defineProps<Props>(), {
  products: () => [],
  columnCount: 2,
  gap: 12,
  minImageHeight: 150,
  maxImageHeight: 300,
  loading: false,
  hasMore: true,
  loadingText: '加载中...',
  showSkeleton: false,
  skeletonCount: 6,
  skeletonColumns: 2,
  emptyImage: 'search',
  emptyDescription: '暂无商品',
  showRetry: true,
  showBackTop: true,
  backTopOffset: 500,
  backTopZIndex: 100,
  autoLoadMore: true,
  loadMoreOffset: 100
})

// Emits
const emit = defineEmits<{
  productClick: [product: ProductItem]
  refresh: []
  loadMore: []
  imageLoad: [product: ProductItem]
  imageError: [product: ProductItem]
  layoutComplete: []
  retry: []
  backTop: []
}>()

// 响应式数据
const refreshing = ref(false)
const waterfallRef = ref<InstanceType<typeof WaterfallContainer>>()
const displayProducts = ref<ProductItem[]>([])

// 计算属性
const showSkeleton = computed(() => {
  return (props.showSkeleton || props.loading) && displayProducts.value.length === 0
})

// 监听props.products变化
watch(
  () => props.products,
  (newProducts) => {
    displayProducts.value = [...newProducts]
  },
  { immediate: true, deep: true }
)

// 生命周期
onMounted(() => {
  if (props.autoLoadMore) {
    setupAutoLoadMore()
  }
})

onUnmounted(() => {
  if (props.autoLoadMore) {
    cleanupAutoLoadMore()
  }
})

// 方法
async function handleRefresh(): Promise<void> {
  refreshing.value = true
  
  try {
    if (props.refresh) {
      const newProducts = await props.refresh()
      displayProducts.value = newProducts
      showToast('刷新成功')
    } else {
      emit('refresh')
    }
  } catch (error) {
    console.error('刷新失败:', error)
    showToast('刷新失败，请重试')
  } finally {
    refreshing.value = false
  }
}

async function handleLoadMore(): Promise<void> {
  if (props.loading || !props.hasMore) return
  
  try {
    if (props.loadMore) {
      const newProducts = await props.loadMore()
      displayProducts.value.push(...newProducts)
    } else {
      emit('loadMore')
    }
  } catch (error) {
    console.error('加载更多失败:', error)
    showToast('加载失败，请重试')
  }
}

function handleProductClick(product: ProductItem): void {
  emit('productClick', product)
}

function handleImageLoad(product: ProductItem): void {
  emit('imageLoad', product)
}

function handleImageError(product: ProductItem): void {
  emit('imageError', product)
}

function handleLayoutComplete(): void {
  emit('layoutComplete')
}

function handleRetry(): void {
  emit('retry')
}

function handleBackTop(): void {
  emit('backTop')
}

// 自动加载更多
let scrollHandler: (() => void) | null = null

function setupAutoLoadMore(): void {
  scrollHandler = () => {
    const scrollTop = window.pageYOffset || document.documentElement.scrollTop
    const windowHeight = window.innerHeight
    const documentHeight = document.documentElement.scrollHeight
    
    if (scrollTop + windowHeight >= documentHeight - props.loadMoreOffset) {
      if (props.hasMore && !props.loading) {
        handleLoadMore()
      }
    }
  }
  
  window.addEventListener('scroll', scrollHandler, { passive: true })
}

function cleanupAutoLoadMore(): void {
  if (scrollHandler) {
    window.removeEventListener('scroll', scrollHandler)
    scrollHandler = null
  }
}

// 添加商品到列表
function addProducts(products: ProductItem[]): void {
  displayProducts.value.push(...products)
}

// 重置列表
function resetProducts(products: ProductItem[]): void {
  displayProducts.value = products
}

// 重新布局
function rebalance(): void {
  nextTick(() => {
    waterfallRef.value?.rebalanceColumns()
  })
}

// 暴露方法给父组件
defineExpose({
  addProducts,
  resetProducts,
  rebalance,
  refresh: handleRefresh,
  loadMore: handleLoadMore
})
</script>

<style scoped>
.product-waterfall-list {
  width: 100%;
  min-height: 100vh;
  background: #f5f5f5;
}

.pull-refresh-wrapper {
  min-height: 100vh;
}

.load-more-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
  background: #f5f5f5;
}

.load-more-trigger {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  background: #fff;
  border-radius: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  cursor: pointer;
  transition: all 0.3s ease;
  color: #666;
  font-size: 14px;
}

.load-more-trigger:hover {
  background: #f8f8f8;
  transform: translateY(-2px);
}

.load-more-trigger:active {
  transform: translateY(0);
}

.no-more {
  padding: 20px;
  background: #f5f5f5;
}

.empty-state {
  padding: 60px 20px;
  background: #f5f5f5;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .load-more-wrapper {
    padding: 16px;
  }
  
  .load-more-trigger {
    padding: 10px 20px;
    font-size: 13px;
  }
  
  .empty-state {
    padding: 40px 16px;
  }
}

/* 动画效果 */
.product-waterfall-list {
  animation: fadeIn 0.3s ease-in-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
</style>